/**
 * 
 */
package com.acc.softmgr.common.genertor.gen;

import java.sql.SQLException;
import java.util.Date;
import java.util.List;

import org.apache.velocity.VelocityContext;

import com.acc.softmgr.common.genertor.bean.ColumnData;
import com.acc.softmgr.common.genertor.utils.CodeResourceUtil;
import com.acc.softmgr.common.genertor.utils.CommUtil;
import com.acc.softmgr.common.genertor.utils.PageParserUtil;
import com.alibaba.fastjson.JSONException;
import com.alibaba.fastjson.JSONObject;

/**
 * 
 * @content 生成Mapper的XML
 * 
 * @date 2017年5月20日
 * 
 * @author OprCalf
 * 
 */
public class GenerateMapperXML extends BaseGenerate {

	public void genMapperXML(String tableName, String pckPath, String mapperXMPPath)
			throws SQLException, JSONException {
		String className = CommUtil.formatTableNameToClassName(tableName);
		List<ColumnData> dataList = createBean.getColumnDatas(tableName);
		VelocityContext context = new VelocityContext();
		context.put("basePackage", CodeResourceUtil.basePackage);
		context.put("createDate", new Date());
		context.put("className", className);

		context.put("initBaseResultMap", initBaseResultMap(dataList));
		context.put("baseColumnList", initBaseColumnList(dataList));
		context.put("tableName", tableName);

		JSONObject json = initPrimaryKey(dataList);
		context.put("priColumnName", json.get("priColumnName"));
		context.put("priFormatColumnName", json.get("priFormatColumnName"));
		context.put("priColumnType", json.get("priColumnType"));
		context.put("priDataType", json.get("priDataType"));

		context.put("initInsert", initInsert(dataList, tableName));
		context.put("initInsertSelective", initInsertSelective(dataList, tableName));

		context.put("initUpdateByExampleSelective", initUpdateByExampleSelective(dataList, tableName));
		context.put("initUpdateByExample", initUpdateByExample(dataList, tableName));
		context.put("initUpdateByPrimaryKeySelective", initUpdateByPrimaryKeySelective(dataList, tableName));
		context.put("initUpdateByPrimaryKey", initUpdateByPrimaryKey(dataList, tableName));

		PageParserUtil.WriterPage(context, "MapperXMLTemplte.ftl", pckPath, mapperXMPPath);
	}

	// 初始化原始MAP列表
	private String initBaseResultMap(List<ColumnData> dataList) {
		StringBuffer str = new StringBuffer();
		for (ColumnData d : dataList) {
			String lowName = CommUtil.formatName(d.getColumnName());
			str.append("<result column=\"" + d.getColumnName() + "\" property=\"" + lowName + "\" />");
		}
		return str.toString();
	}

	// 初始化所有属性
	private String initBaseColumnList(List<ColumnData> dataList) {
		StringBuffer str = new StringBuffer();
		if (dataList != null) {
			for (int i = 0; i < dataList.size(); i++) {
				str.append(dataList.get(i).getColumnName());
				if (i < dataList.size() - 1) {
					str.append(",");
				}
			}
		}
		return str.toString();
	}

	// 初始化主键信息
	private JSONObject initPrimaryKey(List<ColumnData> dataList) {
		JSONObject json = new JSONObject();
		for (ColumnData d : dataList) {
			if ("PRI".equals(d.getColumnKey().toUpperCase())) {
				try {
					json.put("priColumnName", d.getColumnName());// 数据库字段名称
					json.put("priFormatColumnName", d.getFormatColumnName());// JAVA字段名称
					json.put("priColumnType", d.getColumnType());// 数据库原有属性
					json.put("priDataType", d.getDataType());// JAVA属性
				} catch (JSONException e) {
					e.printStackTrace();
				}
			}
		}
		return json;
	}

	// 初始化insert
	private String initInsert(List<ColumnData> dataList, String tableName) throws SQLException {

		String columns = getColumnSplit(dataList);
		String formatColumns = getFormatColumnSplit(dataList);

		String insert = "insert into " + tableName + "(" + columns.replaceAll("\\|", ",") + ")\n values(#{"
				+ formatColumns.replaceAll("\\|", "},#{") + "})";
		return insert.replace("#{createTime}", "now()").replace("#{updateTime}", "now()");
	}

	// 初始化insertSelective
	private String initInsertSelective(List<ColumnData> dataList, String tableName) {

		StringBuffer str = new StringBuffer();
		str.append("insert into " + tableName);
		str.append("\r\t");
		str.append("<trim prefix=\"(\" suffix=\")\" suffixOverrides=\",\">");
		str.append("\r\t");
		for (int i = 0; i < dataList.size(); i++) {
			str.append(
					"<if test=\"" + dataList.get(i).getColumnName() + " != null\">" + dataList.get(i).getColumnName());
			if (i == dataList.size() - 1) {
				str.append("</if>");
			} else {
				str.append(",</if>");
			}
			str.append("\r\t");
		}
		str.append("</trim>");
		str.append("\r\t");

		str.append("<trim prefix=\"values (\" suffix=\")\" suffixOverrides=\",\">");
		str.append("\r\t");
		for (int i = 0; i < dataList.size(); i++) {
			str.append("<if test=\"" + dataList.get(i).getFormatColumnName() + " != null\">#{"
					+ dataList.get(i).getFormatColumnName() + "}");
			if (i == dataList.size() - 1) {
				str.append("</if>");
			} else {
				str.append(",</if>");
			}
			str.append("\r\t");
		}
		str.append("</trim>");
		str.append("\r\t");

		return str.toString();
	}

	// 初始化UpdateByExampleSelective
	private String initUpdateByExampleSelective(List<ColumnData> dataList, String tableName) {

		StringBuffer str = new StringBuffer();
		str.append("update " + tableName);
		str.append("\r\t");
		str.append("<set>");

		for (int i = 0; i < dataList.size(); i++) {
			str.append("<if test=\"record." + dataList.get(i).getFormatColumnName() + " != null\">"
					+ dataList.get(i).getColumnName() + " = #{record." + dataList.get(i).getFormatColumnName() + "}");
			if (i == dataList.size() - 1) {
				str.append("</if>");
			} else {
				str.append(",</if>");
			}
			str.append("\r\t");
		}
		str.append("</set>");
		str.append("\r\t");
		str.append("<if test=\"_parameter != null\"><include refid=\"Update_By_Example_Where_Clause\" /></if>");
		str.append("\r\t");

		return str.toString();

	}

	// 初始化updateByExample
	private String initUpdateByExample(List<ColumnData> dataList, String tableName) {

		StringBuffer str = new StringBuffer();
		str.append("update " + tableName);
		str.append("\r\t");
		str.append("set");
		str.append("\r\t");
		for (int i = 0; i < dataList.size(); i++) {
			str.append("" + dataList.get(i).getColumnName() + " = #{record." + dataList.get(i).getFormatColumnName()
					+ "}");
			if (i == dataList.size() - 1) {
				str.append("");
			} else {
				str.append(",");
			}
			str.append("\r\t");
		}

		str.append("<if test=\"_parameter != null\"><include refid=\"Update_By_Example_Where_Clause\" /></if>");
		str.append("\r\t");

		return str.toString();

	}

	// 初始化updateByPrimaryKeySelective
	private String initUpdateByPrimaryKeySelective(List<ColumnData> dataList, String tableName) {

		StringBuffer str = new StringBuffer();
		String priName = "";
		String priFormatName = "";

		str.append("update " + tableName);
		str.append("\r\t");
		str.append("<set>");
		str.append("\r\t");
		for (int i = 0; i < dataList.size(); i++) {
			if ("PRI".equals(dataList.get(i).getColumnKey())) {
				priName = dataList.get(i).getColumnName();
				priFormatName = dataList.get(i).getFormatColumnName();
			}

			str.append("<if test=\"" + dataList.get(i).getFormatColumnName() + " != null\">"
					+ dataList.get(i).getColumnName() + " = #{" + dataList.get(i).getFormatColumnName() + "}");
			if (i == dataList.size() - 1) {
				str.append("</if>");
			} else {
				str.append(",</if>");
			}
			str.append("\r\t");
		}
		str.append("</set>");
		str.append("\r\t");
		str.append("where " + priName + " = #{" + priFormatName + "}");
		str.append("\r\t");

		return str.toString();
	}

	// 初始化updateByPrimaryKey
	private String initUpdateByPrimaryKey(List<ColumnData> dataList, String tableName) {

		StringBuffer str = new StringBuffer();
		String priName = "";
		String priFormatName = "";
		str.append("update " + tableName);
		str.append("\r\t");
		str.append("set");
		str.append("\r\t");
		for (int i = 0; i < dataList.size(); i++) {
			if (!"PRI".equals(dataList.get(i).getColumnKey())) {
				str.append(
						"" + dataList.get(i).getColumnName() + " = #{" + dataList.get(i).getFormatColumnName() + "}");
				if (i == dataList.size() - 1) {// 去掉主键计算
					str.append("");
				} else {
					str.append(",");
				}
				str.append("\r\t");
			} else {
				priName = dataList.get(i).getColumnName();
				priFormatName = dataList.get(i).getFormatColumnName();
			}
		}

		str.append("where " + priName + " = #{" + priFormatName + "}");
		str.append("\r\t");

		return str.toString();

	}

	private String getColumnSplit(List<ColumnData> columnList) throws SQLException {
		StringBuffer commonColumns = new StringBuffer();
		for (ColumnData data : columnList) {
			commonColumns.append(data.getColumnName() + "|");
		}
		return commonColumns.delete(commonColumns.length() - 1, commonColumns.length()).toString();
	}

	private String getFormatColumnSplit(List<ColumnData> columnList) throws SQLException {
		StringBuffer commonColumns = new StringBuffer();
		for (ColumnData data : columnList) {
			commonColumns.append(data.getFormatColumnName() + "|");
		}
		return commonColumns.delete(commonColumns.length() - 1, commonColumns.length()).toString();
	}
}
